package com.changjiang.luban.utils.file;

import sun.font.FontDesignMetrics;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.geom.AffineTransform;
import java.awt.image.AffineTransformOp;
import java.awt.image.BufferedImage;
import java.io.*;
import java.util.ArrayList;
import java.util.List;

/**
 * ImageUtils
 * Description: 图片处理工具类
 *
 * @author nichangjiang@vip.qq.com
 * @version v0.1
 * @date 2018/6/18 - 22:33
 */
@SuppressWarnings("ALL")
public class ImageUtils {

    public static String IMAGE_TYPE_GIF = "gif";

    public static String IMAGE_TYPE_JPG = "jpg";

    public static String IMAGE_TYPE_JPEG = "jpeg";

    public static String IMAGE_TYPE_BMP = "bmp";

    public static String IMAGE_TYPE_PNG = "png";

    public static String IMAGE_TYPE_PSD = "psd";

    /**
     * 缩放图像——按比例
     *
     * @param srcImageFile 源文件
     * @param result       返回的文件
     * @param scale        比例值
     * @param flag         true 放大 false 缩小
     */
    public static void scale(String srcImageFile, String result, int scale, boolean flag) {
        try {
            // 读入文件
            BufferedImage src = ImageIO.read(new File(srcImageFile));
            // 得到源图宽
            int width = src.getWidth();
            // 得到源图长
            int height = src.getHeight();
            // 放大
            if (flag) {
                width = width * scale;
                height = height * scale;
            } else {
                width = width / scale;
                height = height / scale;
            }
            Image image = src.getScaledInstance(width, height,
                    Image.SCALE_DEFAULT);
            BufferedImage tag = new BufferedImage(width, height,
                    BufferedImage.TYPE_INT_RGB);
            Graphics g = tag.getGraphics();
            // 绘制缩小后的图
            g.drawImage(image, 0, 0, null);
            g.dispose();
            // 输出到文件流
            ImageIO.write(tag, "JPEG", new File(result));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 缩放图像——按高度和宽度缩放
     *
     * @param srcImageFile 源文件
     * @param result       返回的文件
     * @param height       缩放高度
     * @param width        缩放宽度
     * @param supplement   true 补充白色 false 不补充
     */
    public static void scale(String srcImageFile, String result, int height, int width, boolean supplement) {
        try {
            // 缩放比例
            double ratio;
            File f = new File(srcImageFile);
            BufferedImage bi = ImageIO.read(f);
            Image itemp = bi.getScaledInstance(width, height, Image.SCALE_SMOOTH);
            // 计算比例
            if ((bi.getHeight() > height) || (bi.getWidth() > width)) {
                if (bi.getHeight() > bi.getWidth()) {
                    ratio = (new Integer(height)).doubleValue()
                            / bi.getHeight();
                } else {
                    ratio = (new Integer(width)).doubleValue() / bi.getWidth();
                }
                AffineTransformOp op = new AffineTransformOp(AffineTransform
                        .getScaleInstance(ratio, ratio), null);
                itemp = op.filter(bi, null);
            }
            //补白
            if (supplement) {
                BufferedImage image = new BufferedImage(width, height,
                        BufferedImage.TYPE_INT_RGB);
                Graphics2D g = image.createGraphics();
                g.setColor(Color.white);
                g.fillRect(0, 0, width, height);
                if (width == itemp.getWidth(null)) {
                    g.drawImage(itemp, 0, (height - itemp.getHeight(null)) / 2,
                            itemp.getWidth(null), itemp.getHeight(null),
                            Color.white, null);
                } else {
                    g.drawImage(itemp, (width - itemp.getWidth(null)) / 2, 0,
                            itemp.getWidth(null), itemp.getHeight(null),
                            Color.white, null);
                }
                g.dispose();
                itemp = image;
            }
            ImageIO.write((BufferedImage) itemp, "JPEG", new File(result));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


    public static void pressText(String pressText, String srcImageFile, Integer srcImageWideth, Integer srcImageHeight, String fontName, int fontStyle, Color color, int fontSize, int x, int y, float alpha) {
        try {
            File img = new File(srcImageFile);
            Image src = ImageIO.read(img);
            BufferedImage image = new BufferedImage(srcImageWideth, srcImageHeight,
                    BufferedImage.TYPE_INT_RGB);
            Graphics2D g = image.createGraphics();
            g.drawImage(src, 0, 0, srcImageWideth, srcImageHeight, null);
            g.setColor(color);
            g.setFont(new Font(fontName, fontStyle, fontSize));
            g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP,
                    alpha));
            // 在指定坐标绘制水印文字
            pressText = pressText == null ? "" : pressText;
            g.drawString(pressText, x, y);
            g.dispose();
            ImageIO.write(image, "JPEG", new File(srcImageFile));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private static final String DOWN_LOAD_IMG = "C:/temp/qrcode.jpg";


    public static void pressText(String title,String pressText, String srcImageFile, Integer srcImageWideth, int x, int y, float alpha) {
        try {
            Font font = new Font("微软雅黑", Font.BOLD, 40);
            Font titleFont = new Font("微软雅黑", Font.PLAIN, 50);
            Font qrcodeFont = new Font("微软雅黑", Font.BOLD, 40);
            File img = new File(srcImageFile);
            FontDesignMetrics metrics = FontDesignMetrics.getMetrics(font);
            int width = 0;
            int height = metrics.getHeight();
            int imgHeight = 1000;
            int contentWidth = srcImageWideth - x * 2;
            StringBuffer sb = new StringBuffer();
            java.util.List<StringBuffer> stringList = new ArrayList<>();
            for (int i = 0; i < pressText.length(); i++) {
                char c = pressText.charAt(i);
                int nexWidth = 0;
                if (i + 1 < pressText.length()) {
                    nexWidth = metrics.charWidth(pressText.charAt(i + 1));
                }
                sb.append(c);
                if (width + nexWidth <= contentWidth) {
                    width += metrics.charWidth(c);
                    if (i == pressText.length() - 1) {
                        stringList.add(sb);
                    }
                } else {
                    width = 0;
                    stringList.add(sb);
                    sb = new StringBuffer();
                    imgHeight += height + 40;
                }
            }
            BufferedImage bi = new BufferedImage(srcImageWideth, imgHeight, BufferedImage.TYPE_INT_RGB);
            Graphics2D g2 = (Graphics2D) bi.getGraphics();
            g2.setBackground(Color.WHITE);
            g2.clearRect(0, 0, srcImageWideth, imgHeight);
            g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
            g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
            g2.setFont(titleFont);
            FontMetrics fm = g2.getFontMetrics(titleFont);
            g2.setColor(new Color(13, 71, 161));
            g2.drawString(title, (srcImageWideth - fm.stringWidth(title)) / 2, 80);
            Stroke stroke = new BasicStroke(2.0f);
            g2.setStroke(stroke);
            g2.drawLine(x, y - 100, srcImageWideth - x, y - 100);
            g2.drawLine(x, y - 110, srcImageWideth - x, y -110);
            g2.setColor(new Color(66, 66, 66));
            g2.setFont(font);
            for (int i = 0; i < stringList.size(); i++) {
                g2.drawString(String.valueOf(stringList.get(i)), x, y);
                y += height + 30;
            }
            ImageRequest.download("http://qrcode-1251438932.cos.ap-shanghai.myqcloud.com/qr1000001217946522", DOWN_LOAD_IMG);
            File qrcodeImg = new File(DOWN_LOAD_IMG);
            Image src = ImageIO.read(qrcodeImg);
            y += 50;
            g2.drawImage(src, (srcImageWideth - 430) / 2, y, 430, 430, null);
            y += 500;
            g2.setFont(qrcodeFont);
            fm = g2.getFontMetrics(qrcodeFont);
            g2.setColor(new Color(0, 0, 0));
            g2.drawString("长按识别，进入小程序", (srcImageWideth - fm.stringWidth("长按识别，进入小程序")) / 2, y);
            ImageIO.write(bi, "JPEG", new File(srcImageFile));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void fontContent(int wideth, Font font, String pressText, int x, int y) throws IOException {
        FontDesignMetrics metrics = FontDesignMetrics.getMetrics(font);
        int width = 0;
        int height = metrics.getHeight();
        int imgHeight = 200;
        wideth = wideth - x * 2;
        StringBuffer sb = new StringBuffer();
        List<StringBuffer> stringList = new ArrayList<>();
        for (int i = 0; i < pressText.length(); i++) {
            char c = pressText.charAt(i);
            sb.append(c);
            if (width < wideth) {
                width += metrics.charWidth(pressText.charAt(i));
            } else {
                width = 0;
                stringList.add(sb);
                sb = new StringBuffer();
            }
            imgHeight += height;
        }
        BufferedImage bi = new BufferedImage(wideth, imgHeight, BufferedImage.TYPE_INT_RGB);
        Graphics2D g2 = (Graphics2D) bi.getGraphics();
        g2.setBackground(Color.WHITE);
        g2.clearRect(0, 0, wideth, imgHeight);
        g2.setPaint(Color.WHITE);
        for (int i = 0; i < stringList.size(); i++) {
            g2.drawString(String.valueOf(stringList.get(i)), x, y);
            y += height + 12;
        }
        ImageIO.write(bi, "JPEG", new File("C:/temp/null.png"));
    }

    public static void main(String[] args) {

      /*  ImageUtils.pressText("真正厉害的人，都很会浪费时间 有人说，“上班用掉8小时，睡觉用掉8小时，剩下的8小时，才决定一个人的高度。”  与其要把这“3个8”时间段分得清，不如说，对时间的管理理念在影响一个人生活的效率和质量。  很多人把所谓“私人空间”分得很开。  上班，就是在被动把时间安排给一些不得不做的任务；下班了的时间，再也不想让自己继续集中精力，让大脑完全放松，进行“彻底的”娱乐活动……  抓紧每分每秒“享受生活”，生怕浪费时间。  但从某种程度上来说，时间从不应该被割裂开，且本质上也没有性质的区分。  真正需要正确认识并分类的，是我们看待时间的方式。  理解时间在我们心中的本质后，浪费时间，也会是一件很科学的事。  1  先创造想要的生活  时间自然就能“省下来”  拖延症，没有合理计划，盲目忙碌……没有把时间握在自己手里的“现代病”都可以导致时间焦虑。  常常感觉被太多工作、家常拉扯得不得空，但其实是我们没有认清时间的真正存在形式。  首先需要做的，是分清两类时间。  一是必要时间，所谓的unbroken time，指不可避免的事项所花的时间，例如衣食住行、工作、上课……这些时间属于相对固定的时间，不能避免。  二是空余时间，即在必要时间之外的时间碎片。这些时间相对短，更容易被浪费。  例如每一个下班或放学回家的地铁上、排队或等餐的时间。也就是这些时间段，常常引发人的焦虑。  真正心智成熟的人，都懂得如何体面应对这样的时间。  Laura Vanderkam是几大畅销时间管理类书籍作者，她说，人们对她总会抱有误解：你一定是个永远准时的人！你也一定有许多关于整理零碎时间的小窍门。   甚至有想写时间管理书籍的人向她请教：该怎么告诉读者“如何在一天中省下一个小时”来提升自己，长此以往省下的时间？只要能省下零散时间，我们能做到自己想做的任何事情。  而她本人都对此表示怀疑。  Laura说，我们不能通过节省时间创造想要的生活，而是先创造想要的生活，然后时间自然而然就被节省下来了。  比如，一个每天都处在极度繁忙状态的职业女性在家里热水器坏掉，淹了地下室，她从排得密密麻麻的时间表上挤出了七个小时去修整。如果这是计划中要做运动的时间，就肯定会被各种借口耽搁。  时间本身不能增加，但合理的选择，会让时间被更高效地利用。  Laura预约采访一位能兼顾职业和家庭的女性，但计划因为对方要在清晨去徒步而取消。再次见到她，Laura很奇怪她为什么会有时间做这些休闲活动。",
                "C:/temp/null.png", 1200,
                100, 220, 1);*/
    }

    /**
     * 计算文字一段字符串的宽度
     *
     * @param font
     * @param content
     * @return
     */
    public static int getWordWidth(Font font, String content) {
        FontDesignMetrics metrics = FontDesignMetrics.getMetrics(font);
        int width = 0;
        for (int i = 0; i < content.length(); i++) {
            width += metrics.charWidth(content.charAt(i));
        }
        return width;
    }

    /**
     * 计算文字一段字符串的高度
     *
     * @param font
     * @param content
     * @return
     */
    public static int getWordHeight(Font font, String content) {
        FontDesignMetrics metrics = FontDesignMetrics.getMetrics(font);
        int height = metrics.getHeight();
        return height;
    }


    public static void pressImage(String pressImg, Integer pressImgWideth, Integer pressImgHeight) throws IOException {
        File img = new File(pressImg);
        Image src = ImageIO.read(img);
        BufferedImage image = new BufferedImage(pressImgWideth, pressImgHeight,
                BufferedImage.TYPE_INT_RGB);
        Graphics2D g = image.createGraphics();
        g.drawImage(src, 0, 0, pressImgWideth, pressImgHeight, null);
        g.dispose();
        ImageIO.write(image, "JPEG", new File(pressImg));
    }

    /**
     * @param pressImg       水印图片
     * @param pressImgWideth 水印图片宽度
     * @param pressImgHeight 水印图片高度
     * @param srcImageFile   原图
     * @param srcImageWideth 原图宽度
     * @param srcImageHeight 宽度高度
     * @param x              X轴
     * @param y              Y轴
     * @param alpha          透明度
     */
    public static void pressImage(String pressImg, Integer pressImgWideth, Integer pressImgHeight, String srcImageFile, Integer srcImageWideth, Integer srcImageHeight, int x, int y, float alpha) {
        try {
            File img = new File(srcImageFile);
            Image src = ImageIO.read(img);
            BufferedImage image = new BufferedImage(srcImageWideth, srcImageHeight,
                    BufferedImage.TYPE_INT_RGB);
            Graphics2D g = image.createGraphics();
            g.drawImage(src, 0, 0, srcImageWideth, srcImageHeight, null);
            // 水印文件
            Image srcBiao = ImageIO.read(new File(pressImg));
            g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, alpha));
            g.drawImage(srcBiao, x, y, pressImgWideth, pressImgHeight, null);
            // 水印文件结束
            g.dispose();
            ImageIO.write(image, "JPEG", new File(srcImageFile));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static int getLength(String text) {
        int length = 0;
        for (int i = 0; i < text.length(); i++) {
            if ((text.charAt(i) + "").getBytes().length > 1) {
                length += 2;
            } else {
                length += 1;
            }
        }
        return length / 2;
    }


    /**
     * 判断文件是否为图片
     */
    public static boolean isImage(File imageFile) throws FileNotFoundException {
        FileInputStream fis = new FileInputStream(imageFile);
        boolean flag = isImage(fis);
        try {
            fis.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return flag;
    }

    /**
     * 判断文件是不是图片
     */
    public static boolean isImage(InputStream is) {
        Image img = null;
        try {
            img = ImageIO.read(is);
            if (img == null || img.getWidth(null) <= 0 || img.getHeight(null) <= 0) {
                return false;
            }
            return true;
        } catch (Exception e) {
            return false;
        } finally {
            img = null;
        }
    }


    /**
     * 获取图片文件格式
     */
    public static ImageFormat imageFormat(File file) throws FileNotFoundException {
        FileInputStream fis = new FileInputStream(file);
        ImageFormat imgfmt = imageFormat(fis);
        try {
            fis.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return imgfmt;
    }


    /**
     * 获取图片文件的格式
     *
     * @throws IOException 异常
     */
    public static ImageFormat imageFormat(InputStream is) {
        byte[] b = new byte[10];
        int l = -1;

        try {
            l = is.read(b);
        } catch (IOException e) {
            return ImageFormat.UNKNOW;
        }
        if (l == 10) {
            byte b0 = b[0];
            byte b1 = b[1];
            byte b2 = b[2];
            byte b3 = b[3];
            byte b6 = b[6];
            byte b7 = b[7];
            byte b8 = b[8];
            byte b9 = b[9];
            if (b0 == (byte) 'G' && b1 == (byte) 'I' && b2 == (byte) 'F') {
                return ImageFormat.GIF;
            } else if (b1 == (byte) 'P' && b2 == (byte) 'N' && b3 == (byte) 'G') {
                return ImageFormat.PNG;
            } else if (b6 == (byte) 'J' && b7 == (byte) 'F' && b8 == (byte) 'I' && b9 == (byte) 'F') {
                return ImageFormat.JPEG;
            } else {
                return ImageFormat.UNKNOW;
            }
        } else {
            return ImageFormat.UNKNOW;
        }
    }

    /**
     * 图片的格式枚举
     * jpg，png，gif，三种图片的格式名，格式后缀，以及Http的Header：Content-Type信息
     */
    public enum ImageFormat {
        JPEG("jpg", ".jpg", "image/jpeg"),
        PNG("png", ".png", "image/png"),
        GIF("gif", ".gif", "image/gif"),
        UNKNOW("jpg", ".jpg", "image/jpeg");

        private String format;
        private String suffix;
        private String contentType;

        private ImageFormat(String format, String suffix, String contentType) {
            this.format = format;
            this.suffix = suffix;
            this.contentType = contentType;
        }

        public String getFormat() {
            return format;
        }

        public String getSuffix() {
            return suffix;
        }

        public String getContentType() {
            return contentType;
        }
    }
}
